use std::{ffi::{c_char, c_int, CString},os::raw::c_void};

#[repr(C)]
pub struct SampleStruct {
    pub handler: unsafe extern "C" fn(*const c_char, &mut *mut c_char) -> *mut c_void,
}

#[no_mangle]
pub extern "C" fn try_it(_input: SampleStruct) -> c_int {
    println!("==>1<==");
    let input_message: *const c_char =  CString::new("This message comes from rust library's try_it function!").unwrap().into_raw();

    let output_message:&mut *mut c_char = &mut CString::new("This is the initialize message in rust library's try_it function!                               ").unwrap().into_raw();

    unsafe {
        println!("===============================================================");
        (_input.handler)(input_message as *const c_char, output_message);
        println!("Display output message in rust library's try_it function => {}", CString::from_raw(output_message.as_mut().unwrap()).to_str().unwrap());
        println!("Unsafe Invoke terminated");
    }
    println!("==>2<==");
    0
}

unsafe extern "C" fn handler_process(_input_message: *const c_char, mut _output_message: &mut *mut c_char) -> *mut c_void {
    let v: i32 = 0;

    println!("Display input message in rust library's handler_process function => {}", CString::from_raw(_input_message as *mut c_char).into_string().unwrap());

    v as *mut c_void
}

pub fn test_wrapper() {
    let args: SampleStruct = SampleStruct{
        handler : handler_process
    };

    try_it(args);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        test_wrapper()
    }
}
